package com.linxcool.action;

import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.Observable;
import java.util.TreeMap;

import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.StringEntity;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.util.Log;


/**
 * 基础动作类
 * @author: linxcool.hu
 */
public abstract class ActionSupport extends Observable implements HttpListener,Runnable{
	
	private static final String TAG="ActionSupport";
	
	// 动作ID列表
	
	// 响应状态结果
	public static final int SUCCESS = 0;	//成功
	public static final int FAILURE = 1;	//失败
	public static final int ERROR = 2;		//错误
	
	//上下文对象
	protected Context context;
	
	//动作信息列表
	protected int actionId;
	protected HttpHelper httpHelper;
	
	protected String pContent;
	protected TreeMap<String, String> gContent;
	
	//响应信息
	protected String response;
	protected int errorCode;
	protected String errorMsg;
	
	/**
	 * 获取通信失败时的错误码
	 * @return
	 */
	public int getErrorCode(){
		return errorCode;
	}
	
	/**
	 * 获取响应的消息
	 * @return
	 */
	public String getErrorMsg() {
		return errorMsg;
	}
	
	public Context getContext() {
		return context;
	}
	
	public ActionSupport(Context context,int actionId){
		this.context = context;
		this.actionId = actionId;
		
		httpHelper = new HttpHelper(context);
		httpHelper.setMethod(HttpHelper.HTTP_METHOD_POST);
		
		gContent = new TreeMap<String, String>();
	}

	/**
	 * 执行网络请求动作
	 */
	public void actionStart(){
		try {
			if(httpHelper.getMethod() == HttpHelper.HTTP_METHOD_POST){
				doRequest(getURL(), pContent);
			} else {
				doRequest(getURL(), gContent);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 重写以传入基本信息 未被任何方法调用 仅用于功能性设计
	 * @param jsonObj
	 * @throws JSONException
	 */
	protected void putBasicData(JSONObject jsonObj) throws JSONException{
		//Empty
	}
	
	protected void putBasicData() throws JSONException{
		//Empty
	}
	
	/**
	 * 重写以传入对应业务所需的数据 未被任何方法调用 仅用于功能性设计
	 * @param datas
	 */
	public abstract void putReqData(Object... datas);
	
	public void doRequest(String url,Object content) throws UnsupportedEncodingException{
		Log.d(TAG, "action request url is "+url);
		
		HttpUriRequest request = null;
		
		if(content == null){
			request = httpHelper.createHttpRequest(url);
			httpHelper.request(request, this);
			return;
		}
		
		switch (httpHelper.getMethod()) {
		case HttpHelper.HTTP_METHOD_POST:
			request = httpHelper.createHttpRequest(url);
			HttpPost post = (HttpPost) request;
			post.setEntity(new StringEntity((String)content));
			break;
		case HttpHelper.HTTP_METHOD_GET:
			@SuppressWarnings("unchecked")
			TreeMap<String, String> kvs = (TreeMap<String, String>) content;
			StringBuilder sb = new StringBuilder(url + "?");
			Iterator<String> k = kvs.keySet().iterator();
			while(k.hasNext()){
				sb.append(k + "=" + kvs.get(k) + "&");
			}
			url = sb.toString();
			request = httpHelper.createHttpRequest(url);
			break;
		}
		
		httpHelper.request(request, this);
	}
	
	@Override
	public void onComplete(String response) {
		Log.d(TAG, "action response json is "+response);
		this.response=response;
		((Activity)context).runOnUiThread(this);
	}

	@Override
	public void onError(int code,String msg) {
		Log.e(TAG,"do action response error");
		errorMsg=msg;
		response=null;
		((Activity)context).runOnUiThread(this);
	}
	
	/**
	 * 获取网络请求的地址 请根据动作ID筛选
	 * @return
	 */
	protected abstract String getURL();

	@Override
	public void run() {
		try {
			setChanged();
			if(response == null){
				notifyObservers(ERROR);	
				return;
			}
			JSONObject obj = new JSONObject(response);
			int code=obj.getInt("code");
			if(code==HttpHelper.RES_CODE_SUCCESS){
				onSuccess(obj);
				notifyObservers(SUCCESS);
			}else{
				if(!obj.isNull("msg"))errorMsg=obj.getString("msg");
				notifyObservers(FAILURE);
			}
		} catch (Exception e) {
			Log.e(TAG, "parse json error on action run method");
			e.printStackTrace();
			errorMsg="parse response json error";
			notifyObservers(ERROR);
		}
	}
	
	/**
	 * 网络请求成功后将回调以下方面
	 * @param obj
	 * @throws Exception
	 */
	public abstract void onSuccess(JSONObject obj) throws Exception;
	
}
